package com.cloud.logger.zchain.zchainclient.advice;

import com.alibaba.fastjson.JSONObject;
import com.cloud.logger.zchain.core.common.entity.AngelaLoggerEntity;
import com.cloud.logger.zchain.core.common.entity.builder.AngelaLoggerEntityBuilder;
import com.cloud.logger.zchain.core.common.threadlocal.LoggerThreadLocal;
import com.cloud.logger.zchain.zchainclient.util.AngelaAopLogger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @Author: wcy
 * @Description:
 * @Date: Created in 2017/12/21 17:44
 * @Modified By:
 */
public class ZchainAdvice {
    public void pointCut() {
    }

    public void after(JoinPoint joinPoint) {
    }

    public void before(JoinPoint joinPoint) {
    }

    public void afterReturning(JoinPoint joinPoint, Object returnVal) {
    }

    public Object around(ProceedingJoinPoint pjp) {
        long start = System.currentTimeMillis();
        String className = getRequestUrl();
        Object obj = null;
        boolean error = false;
        try {
            //继续执行
            obj = pjp.proceed();
        } catch (Throwable ex) {
            //将错误输出到控制台
            ex.printStackTrace();
            error = true;
        }
        long end = System.currentTimeMillis();
        if(error) {
            JSONObject rs = new JSONObject();
            rs.put("status", -999);
            rs.put("data", "error");
            obj = rs;
            System.out.println(rs.toJSONString());
        } else {
        }

        long elapsedTime = end - start;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        AngelaLoggerEntity logger = AngelaLoggerEntityBuilder.anAngelaLoggerEntity()
                .withResult(JSONObject.toJSONString(obj))
                .withMethod(request.getMethod())
                .withSourceIP(getIpAddress(request))
                .withElapsedTime(elapsedTime)
                .withInterfaceIp(String.valueOf(request.getRequestURL()+
                        (request.getQueryString()==null?"":("?"+request.getQueryString()))))
                .withInterfaceName(request.getRequestURI())
                .withParms(JSONObject.toJSONString(Arrays.toString(pjp.getArgs())))
                .withTenentId(request.getParameter("tenentId"))
                .withUuid(LoggerThreadLocal.getLoggerId()).build();
        AngelaAopLogger.loggerInterceptor(logger);
        System.out.println(JSONObject.toJSONString(obj));
        return obj;

    }

    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    //这一步将永远都不会走，因为上面不会抛出错误异常
    public void afterThrowing(JoinPoint point, Throwable error) {
        String className = getRequestUrl();
    }

    /**
     * 获取Request Url
     * @return
     * @throws Exception
     *
     */
    public static String getRequestUrl() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        StringBuffer url = request.getRequestURL();
        return url.toString();
    }
}
